#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "Globales.h"
#include "TLexico.h"
#include "TLista.h"

void TLista_Crear(TListaSimple* pLs, int TamanioDato) {
  pLs->Corriente = NULL; 
  pLs->Primero = NULL;
  pLs->TamanioDato = TamanioDato;
}

void TLista_Vaciar(TListaSimple *pLs) {
  TNodoSimple* pNodo;
  TNodoSimple* siguiente;
  for(pNodo = pLs->Primero;(pNodo);pNodo=siguiente) {
    siguiente = pNodo->Siguiente;
    free(pNodo->Elem);
    free(pNodo);
  }
  pLs->Primero=pLs->Corriente=NULL;
}

eBoolean TLista_Vacia(TListaSimple Ls) {
  if (Ls.Primero == NULL) {
    return ebTrue;
  } else {
    return ebFalse;
  }
}

void TLista_ElemCorriente(TListaSimple Ls, void *pE) {
  memcpy(pE, Ls.Corriente->Elem, Ls.TamanioDato);
}

void TLista_ModifCorriente(TListaSimple *pLs, void* pE) {
  memcpy(pLs->Corriente->Elem, pE, pLs->TamanioDato);
}

eBoolean TLista_MoverCorriente(TListaSimple *pLs, TMovimiento_Ls M) {
  switch (M) {
    case LS_PRIMERO:
      pLs->Corriente = pLs->Primero;
      break;
    case LS_SIGUIENTE:
      if (pLs->Corriente->Siguiente == NULL)
        return ebFalse;
      else
        pLs->Corriente = pLs->Corriente->Siguiente;
      break;
    case LS_ANTERIOR:
      return ebFalse;
  }
  return ebTrue;
}

void TLista_BorrarCorriente(TListaSimple *pLs) {
  TNodoSimple* PNodo = pLs->Corriente;
  if (pLs->Corriente == pLs->Primero) {
    pLs->Primero = pLs->Corriente->Siguiente;
    pLs->Corriente = pLs->Primero;
  } else {
    TNodoSimple *PAux=pLs->Primero;
    while (PAux->Siguiente != pLs->Corriente)
    PAux = PAux->Siguiente;
    PAux->Siguiente=pLs->Corriente->Siguiente;
    if (PAux->Siguiente)
    pLs->Corriente = PAux->Siguiente;
    else
    pLs->Corriente = PAux;
  }
  free(PNodo->Elem);
  free(PNodo);
}

eBoolean TLista_Insertar(TListaSimple *pLs, TMovimiento_Ls M, void* pE) {
  TNodoSimple *pNodo = (TNodoSimple*) malloc(sizeof(TNodoSimple));
  if (!pNodo)
    return ebFalse;
  if ((pLs->Primero == NULL) || (M==LS_PRIMERO) || ((M==LS_ANTERIOR) && (pLs->Primero==pLs->Corriente))) {
    pNodo->Siguiente = pLs->Primero;
    pLs->Primero = pLs->Corriente = pNodo;
  } else {
    if (M == LS_SIGUIENTE) {
      pNodo->Siguiente = pLs->Corriente->Siguiente;
      pLs->Corriente->Siguiente = pNodo;
    } else {
      TNodoSimple *pAux=pLs->Primero;
      while (pAux->Siguiente!=pLs->Corriente)
      pAux = pAux->Siguiente;
      pAux->Siguiente = pNodo;
      pNodo->Siguiente = pLs->Corriente;
    }
  }
  pNodo->Elem = malloc (pLs->TamanioDato);
  memcpy(pNodo->Elem, pE, pLs->TamanioDato);
  pLs->Corriente=pNodo;
  return ebTrue;
}
